//
//  BAOAuthViewController.swift
//  BAweibo
//
//  Created by baggio on 2017/8/5.
//  Copyright © 2017年 baggio. All rights reserved.
//

import UIKit
import YYModel
import AFNetworking
import SVProgressHUD

class BAOAuthViewController: UIViewController {
    
    override func loadView() {
        view = loginWebView
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        
        setUpUI()
    }
    
    func setUpUI(){
        setUpNav()
    }
    
    func setUpNav(){
        navigationItem.leftBarButtonItem=UIBarButtonItem(title: "取消", imgName: nil, target: self, action: #selector(cancelClick))
        navigationItem.rightBarButtonItem=UIBarButtonItem(title: "自动填入", imgName: nil, target: self, action: #selector(autoFillClick))
        
        navigationItem.title="微博登录"
    }
    
    //认证页面，里面是一个 UIWebView，懒加载
    //要使用 http 请求，在 plist 添加 Add Transport Security Settings，在里面添加：allow arbitrary loads --- YES
    fileprivate lazy var loginWebView:UIWebView={
        let webView = UIWebView()
        
        //设置代理，监听response，需要实现协议 UIWebViewDelegate
        webView.delegate=self
        
        //请求格式 https://api.weibo.com/oauth2/authorize?client_id=123050457758183&redirect_uri=http://www.example.com
        //我的 https://api.weibo.com/oauth2/authorize?client_id=3462607751&redirect_uri=https://www.baidu.com
        let urlString="https://api.weibo.com/oauth2/authorize?client_id=\(BA_Weibo_AppKey)&redirect_uri=\(BA_Weibo_Redirect_Uri)"
        guard let url=URL(string: urlString) else{
            return webView
        }
        let request=URLRequest(url: url)
        
        //加载 Request
        webView.loadRequest(request)
        
        return webView
    }()
}

/*为了代码整齐，一般把功能相近的方法放在一个分类（extension）中，（当然，也可以不用分类）
  分类中的 private 方法要让主类和其他分类能访问到，必须改成 @objc fileprivate func
  当然，也可以不写 private，但是会给主类和其他分类以外的类访问到，不想这样
 */
extension BAOAuthViewController{
    //取消，关闭页面
    @objc fileprivate func cancelClick(){
        self.dismiss(animated: true, completion: nil)
    }
    
    //自动填入
    @objc fileprivate func autoFillClick(){
        print("自动填入")
        //js注入 document.getElementById('userId').value='jubeisi0516873@163.com',document.getElementById('passwd').value='958794'
        let jsString="document.getElementById('userId').value='\(BA_Weibo_LoginName)',document.getElementById('passwd').value='\(BA_Weibo_Password)'"
        loginWebView.stringByEvaluatingJavaScript(from: jsString)
    }
}


//设置代理，监听response，需要实现协议 UIWebViewDelegate
extension BAOAuthViewController:UIWebViewDelegate{
    func webViewDidStartLoad(_ webView: UIWebView) {
        SVProgressHUD.show()
    }
    
    func webViewDidFinishLoad(_ webView: UIWebView) {
        SVProgressHUD.dismiss()
    }
    
    func webView(_ webView: UIWebView, didFailLoadWithError error: Error) {
    }
    
    
    //监听 webView 将要加载的请求，这里的 request 就是 同意授权后会重定向 http://www.example.com/response&code=CODE，要截取 CODE
    //返回值表示是否加载这个请求，如果不实现该代理方法 默认所有请求都加载
    func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
        
        //print(request.url?.absoluteString) //注意：有多个 url
        /*
         Optional("https://api.weibo.com/oauth2/authorize")
         Optional("https://www.baidu.com/?code=0d6785ab08700580d6dcb1c1b3ecf05b")
         Optional("https://m.baidu.com/?code=0d6785ab08700580d6dcb1c1b3ecf05b&from=844b&vit=fps")
         */
 
        // if let xxx,xxx连写，一般不会联想 redirectUrlStr.hasPrefix 不会联想
        if let urlStr=request.url?.absoluteString,urlStr.hasPrefix(BA_Weibo_Redirect_Uri){
            //print(request.url?.query) query 是参数
            //Optional("code=5657b541e1ba75a28258876ad89d1b4b")
            guard let query=request.url?.query else{
                return false
            }
            let code=query.substring(from: "code=".endIndex)
            print("code=\(code)")
            
            //获取 AccessToken
//            loadAccessToken(code: code)
            
            //使用 封装到 BAOAuthViewModel 中的方法
            //改用 BAOAuthViewModel 的单例
//            let oAuthViewMode=BAOAuthViewModel()
//            oAuthViewMode.loadAccessToken(code: code, finished: { (isSucceeded) in
            BAOAuthViewModel.share.loadAccessToken(code: code, finished: { (isSucceeded) in
                if isSucceeded{
                    print("oAuthViewMode 成功")
                    
                    //要关闭当前控制器
                    self.dismiss(animated: false, completion: { 
                        //发送切换根控制器的通知 -> BAWelcomeViewController
                        NotificationCenter.default.post(name: BA_NOTIFICATION_SWITCH_ROOT_VC, object: "fromOAuthVC2WelcomeVC")
                    })
                }else{
                    print("oAuthViewMode 失败")
                    return
                }
            })
        }
        
        return true
    }
}

/*
 封装到 BAOAuthViewModel 中
 
//访问网络
extension BAOAuthViewController {
    
    //获取 AccessToken
    func loadAccessToken(code:String){
        let urlString="https://api.weibo.com/oauth2/access_token"
        let params=[
            "client_id":BA_Weibo_AppKey,
            "client_secret":BA_Weibo_AppSecret,
            "grant_type":"authorization_code",
            "code":code,
            "redirect_uri":BA_Weibo_Redirect_Uri
        ]
        
        BANetworkingTools.share.request(type: BANetworkingToolsType.post, urlString: urlString, parameters: params, success: { (response) in
            //print(response)
            /*
             Optional({
                "access_token" = "2.002tCPqBH9k1mD0a7c8e7d1bdIXX1D";
                "expires_in" = 157679999;
                "remind_in" = 157679999;
                uid = 1688088343;
             })
             
             经测试，code 每次都不一样，但是 access_token 都一样
             */
            
            //json object 如果不空就转 dict，再 dict 转 model
            guard let res=response as? [String:Any] else{
                return
            }
            
            // 用 YYModel
            // 加上 guard 是为了把 oAuthModel 从可选值变成必选值，后面用起来方便些
            guard let oAuthModel = BAOAuthModel.yy_model(withJSON: res) else{
                return
            }
//            //用 KVC
//            let oAuthModel = BAOAuthModel(dict: res)
            print(oAuthModel)
            
            //获取用户信息
            //在闭包中访问分类，self 不能少
            self.loadUserInfo(oAuthModel: oAuthModel)
            
 
        }) { (error) in
            print("loadAccessToken 失败",error)
        }
        
        
        /*
         因为 AFN 已经把返回的数据进行了反序列化，所以看不出原始数据类型，
         用这种方式可以看出来 expires_in 是 Int，不是官方文档写的 String。"remind_in":"157679999","expires_in":157679999
         */
//        let manager:AFHTTPSessionManager=AFHTTPSessionManager()
//        //设置数据格式是二进制
//        manager.responseSerializer=AFHTTPResponseSerializer()
//        //用 AFN 中的 post 方法
//        manager.post(urlString, parameters: params, progress: nil, success: { (_, result) in
//            let json=NSString(data: (result as! NSData) as Data, encoding:String.Encoding.utf8.rawValue)
//            print(json)
//        }, failure: nil)
  
    }
    
    
    //获取用户信息，通过 access_token 和 uid 获取 screen_name 和 avatar_large
    func loadUserInfo(oAuthModel:BAOAuthModel){
        let urlString="https://api.weibo.com/2/users/show.json"
        let params=[
            "access_token":oAuthModel.access_token,
            "uid":oAuthModel.uid
        ]
        
        BANetworkingTools.share.request(type: .get, urlString: urlString, parameters: params, success: { (response) in
            //print(response)
            //json object 转 dict
            guard let res=response as? [String:Any] else{
                return
            }

            //res["screen_name"] 是 Any?，要转成 String?
            oAuthModel.screen_name=res["screen_name"] as? String
            oAuthModel.avatar_large=res["avatar_large"] as? String
            print(oAuthModel)
       
            //归档，保存到沙盒
            self.saveOAuthModelToSandbox(oAuthModel: oAuthModel)
            
        }) { (error) in
            print("loadUserInfo 失败",error)
        }
    }
}
*/


/*
 封装到 BAOAuthViewModel 中
 
//oAuthModel 归档/解档
extension BAOAuthViewController{
    
    //保存 oAuthModel 数据到沙盒
    func saveOAuthModelToSandbox(oAuthModel:BAOAuthModel) {
    
        //沙盒路径
        let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).last!
        //在 path 下面自己定义一个文件 oAuthModel.plist
        //String 没有拼接方法，所以要转成 NSString
        let file = (path as NSString).appendingPathComponent("oAuthModel.plist")
        ///Users/baggio/Library/Developer/CoreSimulator/Devices/EB1EEAB5-36D1-421C-9C44-ED6C04D8FFA1/data/Containers/Data/Application/487D5EFA-F3E6-431C-9E15-5C6D0076CD6B/Documents/oAuthModel.plist
        print(file)
        
        //归档
        NSKeyedArchiver.archiveRootObject(oAuthModel, toFile: file)
    }
    
    //从沙盒获取 oAuthModel 数据
    func getOAuthModelFromSandbox() -> BAOAuthModel? {
        let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).last!
        let file = (path as NSString).appendingPathComponent("oAuthModel.plist")
        
        //解档
        let result = NSKeyedUnarchiver.unarchiveObject(withFile: file) as? BAOAuthModel
        return result
    }
 }
 */

